在新增資料排序的功能之前,先新增一個 Python 檔:
$ touch server/app/blog/graph/orders.py
接著編輯server/app/blog/graph/orders.py
:
import strawberry
import strawberry_django
from server.app.blog import models as blog_models
@strawberry_django.order(blog_models.Post)
class PostOrder:
published_at: strawberry.auto
@strawberry_django.order(blog_models.Tag)
class TagOrder:
name: strawberry.auto
然後有兩種方式可以設定排序:
一種是加在型態上面,讓所有有用到那個型態的地方都可以對該型態的資料排序,下面用標籤來做示範,編輯server/app/blog/graph/types.py
:
# ... 省略
from server.app.blog import models as blog_models
+from server.app.blog.graph import orders as blog_orders
# ... 省略
-@strawberry_django.type(blog_models.Tag)
+@strawberry_django.type(blog_models.Tag, order=blog_orders.TagOrder)
class Tag:
name: str
上面的查詢可以看到,文章的查詢裡面可以在文章的標籤欄位做排序。
另一種設定排序的方式加在欄位上面,就是只在有需要用到排序的地方使用,下面在server/app/blog/graph/queries.py
進行編輯:
# ... 省略
+from server.app.blog.graph import orders as blog_orders
from server.app.blog.graph import types as blog_types
# ... 省略
@strawberry.type
class Query:
- posts: list[blog_types.Post] = strawberry_django.field()
+ posts: list[blog_types.Post] = strawberry_django.field(order=blog_orders.PostOrder)
# ... 省略
上面的查詢可以看到,可以對文章的發布時間做排序,然後因為標籤是在型態上加上排序功能,所以在標籤的查詢上也可以做資料排序。
由於 strawberry_django 還是一個發展中的套件,目前排序功能上還有許多問題與缺少的功能:
在 strawberry_django 中加上分頁功能是很簡單的,只需要在欄位或是型態上設定pagination=True
就可以了,下面以文章的查詢為例:
# ... 省略
@strawberry.type
class Query:
- posts: list[blog_types.Post] = strawberry_django.field(order=blog_orders.PostOrder)
+ posts: list[blog_types.Post] = strawberry_django.field(
+ order=blog_orders.PostOrder,
+ pagination=True,
+ )
# ... 省略
strawberry_django 提供的分頁功能的風格是基於位移的分頁(Offset-Based Pagination):
由於 strawberry_django 還是一個發展中的套件,目前分頁功能上還有許多問題與缺少的功能:
最後把缺少的User
型態補上,首先建立一個新的應用程式:
$ cd django-graphql-tutorial/server/app
$ django-admin startapp authentication
接著設定應用程式名稱,並註冊應用程式到 Django:
# server/app/authentication/apps.py
from django.apps import AppConfig
class AuthenticationConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
+ name = "server.app.authentication"
# server/settings.py
# ... 省略
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_extensions",
"server.app.blog",
+ "server.app.authentication",
]
# ... 省略
接下來在authentication
內增加graph
模組:
$ mkdir -p server/app/authentication/graph
$ touch server/app/authentication/graph/__init__.py
$ touch server/app/authentication/graph/types.py
在server/app/authentication/graph/types.py
中新增以下程式碼:
import strawberry_django
from django.contrib.auth import get_user_model
__all__ = ("User",)
USER_MODEL = get_user_model()
@strawberry_django.type(USER_MODEL)
class User:
username: str
first_name: str
last_name: str
email: str
最後將原本部落格應用程式裡的author_id
改成author
:
# server/app/blog/graph/types.py
# ... 省略
+from server.app.authentication.graph import types as auth_types
from server.app.blog import models as blog_models
from server.app.blog.graph import orders as blog_orders
# ... 省略
@strawberry_django.type(blog_models.Post)
class Post:
id: uuid.UUID # noqa: A003
slug: str
- author_id: strawberry.ID
+ author: auth_types.User
# ... 省略
# ... 省略
@strawberry_django.type(blog_models.Comment)
class Comment:
id: uuid.UUID # noqa: A003
post: Post
parent: typing.Optional["Comment"]
- author_id: strawberry.ID | None
+ author: auth_types.User | None
content: str
這次修改內容可以參考 Git commit:https://github.com/JiaWeiXie/django-graphql-tutorial/commit/0391081075600ac3a18362088a815772f1e6fa0a